#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@File ：OrderLogic.py
@Author ：zqy
@Email : zqingy@work@163.com 
@note: 
"""
from typing import List, Dict

from flask import g

from application.logic import BaseLogic
from application.util.MysqlUtil import mysql_session, paginate_query
from application.model.ProductModel import Product
from application.mapper.OrderMapper import OrderMapper
from application.model.OrderModel import Order, OrderItem, OrderStatus
from application.Parser.OrderParser import OrderValidator
from application.logic.CartLogic import CartLogic
from application.exception.BasicException import BasicException
from application.enumeration.StatusCodeEnum import StatusCodeEnum


class OrderLogic(BaseLogic):
    """

    """
    model: Order = Order  # 定义模型
    mapper: OrderMapper = OrderMapper  # 定义mapper
    validator: OrderValidator = OrderValidator

    @classmethod
    def add(cls, params):
        cart_items: List[Dict] = CartLogic.mapper.get_cart_item_by_user_id(g.user.id, params.get("cart_ids"))
        if not cart_items:
            return {'message': 'Cart is empty'}

        cart_ids = []
        total_price = 0
        for row in cart_items:
            cart_ids.append(row["id"])
            total_price = row["total_price"]

        order = Order(user_id=g.user.id, total_price=total_price)
        mysql_session.add(order)
        mysql_session.flush()  # 获取 order.id

        for item in cart_items:
            order_item = OrderItem(order_id=order.id, product_id=item["product_id"], quantity=item["quantity"])
            mysql_session.add(order_item)
            product = Product.query.filter_by(id=item["product_id"]).first()
            product.stock -= item["quantity"]
            if product.stock < 0:
                raise BasicException(status_code=StatusCodeEnum.VALIDATOR_ERROR.value, error_message=f"产品:{product.name}库存不足")
            mysql_session.add(product)
            mysql_session.flush()
        CartLogic.mapper.delete_by_ids(cart_ids, autocommit=False)

        try:
            mysql_session.commit()
        except Exception as e:
            mysql_session.rollback()
            return {'message': 'Failed to create order', 'error': str(e)}
        return {'message': 'Order created', 'order_id': order.id}

    @classmethod
    def cancel(cls, _id):
        order = Order.query.filter_by(id=_id).first()
        if not order:
            raise BasicException(status_code=StatusCodeEnum.ERROR.value, error_message="订单不存在")
        if order.user_id!= g.user.id:
            raise BasicException(status_code=StatusCodeEnum.ERROR.value, error_message="订单不存在")
        order.status = OrderStatus.CANCELLED
        mysql_session.add(order)

        for item in order.items:
            product = Product.query.filter_by(id=item.product_id).first()
            product.stock += item.quantity
            mysql_session.add(product)
            cart_it = CartLogic.model(user_id=g.user.id, product_id=item.product_id, quantity=item.quantity, selected=True)
            mysql_session.add(cart_it)

        try:
            mysql_session.commit()
        except Exception as e:
            mysql_session.rollback()
            return {'message': 'Failed to cancel order', 'error': str(e)}
        return {'message': 'Order canceled', 'order_id': order.id}

    @classmethod
    def get_list(cls, params: dict) -> dict:
        """
        获取用户信息列表
        :param params
        :return: {
                    items: [...],
                    total, page_size, current_page
                }
        """
        current_page = params.get("current_page", 1)
        page_size = params.get("page_size", 10)
        _filters = [Order.user_id == g.user.id]
        query = Order.query.filter(*_filters).order_by(Order.id.desc())
        res, total = paginate_query(query, current_page, page_size)
        result: dict = dict(items=[], total=total, page_size=page_size,current_page=current_page)
        for order in res:
            order_info = order.to_dict()
            for item in order.items:
                _item = item.to_dict()
                _item["product_name"] = Product.query.filter_by(id=item.product_id).first().name
                _item["product_image_url"] = Product.query.filter_by(id=item.product_id).first().image_url
                _item["product_price"] = Product.query.filter_by(id=item.product_id).first().price
                order_info.setdefault("items", []).append(_item)
            result['items'].append(order_info)
        return result
